package cn.opencodes.framework.core.log;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.opencodes.framework.core.vo.AccessLog;
import cn.opencodes.framework.core.vo.MaliciousLog;
import cn.opencodes.framework.core.vo.OperationLog;

/**
 * 日志处理
 * @author HJ
 */
public abstract class LogsHandle {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private ExecutorService executorService = Executors.newSingleThreadExecutor();
	private ConcurrentLinkedQueue<Object> buffers =  new ConcurrentLinkedQueue<Object>();
	private int logMax = 10;
	
	public abstract void logsHandle(List<AccessLog> alogs, List<MaliciousLog> mlogs, List<OperationLog> ologs);
	
	// 日志收集
	public void collectLog(Object log){
		logger.debug("日志加入缓冲区：\n{}", log.toString());
		buffers.offer(log);
		if(buffers.size() >= logMax){
			if( !buffers.isEmpty() ){
				executorService.submit(new HandleLogRunnable());
			}
		}
	}
	
	/**
     * 等待任务处理完毕
     * 然后关闭线程池
     */
    public void closeLog(){
    	logger.debug("关闭日志时发现缓存区日志未处理,正在处理...");
        if( !buffers.isEmpty() ){
        	logsHandle();
        }
    	logger.debug("处理完毕,已关闭日志处理线程池");
        executorService.shutdown();
    }
	
	// 处理日志线程，异步使用
    private class HandleLogRunnable implements Runnable{
        @Override
        public void run() {
        	logsHandle();
        }    
    }

    private void logsHandle(){
    	int len = buffers.size();
    	logger.debug("缓冲区已达到限制数: {}, 准备处理日志", len);
    	//日志对象收集
    	List<AccessLog> alogs = new ArrayList<AccessLog>();
    	List<MaliciousLog> mlogs = new ArrayList<MaliciousLog>();
    	List<OperationLog> ologs = new ArrayList<OperationLog>();
    	Object log = null;
        for(int i=0;i<len;i++){
        	log = buffers.poll();
        	if (log instanceof AccessLog) {
        		alogs.add((AccessLog)log);
			}else if (log instanceof MaliciousLog) {
				mlogs.add((MaliciousLog)log);
			}else {
				ologs.add((OperationLog)log);
			}
        }
        // 处理各日志集合
        logsHandle(alogs, mlogs, ologs);
        logger.debug("缓冲区中的日志处理完毕");
    }
}
